import com.mind.jenkins.pipeline.utils.BuildConfig

def call() {
    dockerNode.helmBuildDocker {
        BuildConfig buildConfig
        boolean isSuccess = false
        def causes = currentBuild.getBuildCauses()
        def buildUser = causes[0]?.userId ?: 'Unknown'
        echo "Build User: ${buildUser}"
        try {
            if ("${ENV}" == "EVOFLOW-PROD"){
                stage('部署生产之前二次确认') {
                    try {
                        input(message: "确定发布环境 ${ENV} 的 ${BRANCH}分支？", , id: "CustomId", parameters: [choice(choices: ['确认上线'], description: '', name: 'DEPLOY_RESULT')])
                    } catch (e) {
                        if (e instanceof org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) {
                            currentBuild.result = 'FAILURE'
                            error("Deployment aborted by user.")
                        } else {
                            throw e
                        }
                    }
                }
            }
            stage('拉取代码') {
                //checkout scm
                checkout([
                        $class           : 'GitSCM',
                        branches         : [[name: BRANCH]],
                        userRemoteConfigs: scm.userRemoteConfigs
                ])
            }
            echo "当前发布环境：${ENV}, 当前发布分支：${BRANCH}"
            echo "灰度：${Grayscale} ${GrayscaleType}"


            String appname = jobUtil.getAppNameFromJob()
            echo "当前服务名：${appname}"

            Object commitInfo = jobUtil.getCommitInfo()

            String imageAddr = jobUtil.getImageAdd(ENV)


            // 获取chartname，为了检查镜像是否存在
            String chartname  = sh(returnStdout: true, script: "cat ./release/docker/env.sh| grep DOCKER_IMAGE_NAME= | cut -d = -f 2 | tr -d '\n'")
            String namespace =  sh(returnStdout: true, script: "cat ./release/docker/env.sh| grep K8S_NAMESPACE  | cut -d = -f 2 | tr -d '\n'")

            String imageName

            String coskey

            def serverEnv = []

            String nodejsVersion

            if (params.nodejsVersion == null){
                nodejsVersion = "nodejs-v14"
            }else{
                nodejsVersion = params.nodejsVersion
            }

            stage('安装npm依赖') {
                // 检查镜像是否存在
                def imageExists = sh(script: "docker image ls ${imageAddr}/${chartname} | grep ${commitInfo.version} || true", returnStdout: true).trim()
                if (imageExists) {
                    echo '镜像已存在, 外层npm install跳过'
                    return
                }

                //   sh 'export process.env.CI=false'
                String buildType = params.buildType

                nodejs(nodejsVersion){

                    // 提取公共操作
                    // sh 'npm config set registry http://10.0.5.33:6532/;'
                    sh 'rm -rf build' // 删除上次构建的文件
                    sh 'rm -rf node_modules'

                    // 确定构建命令和目录名
                    def buildCmd = ''
                    def dirName = ''
                    if (appname in ["evoflow-web-mobile", "evoflow-web-pc", "evoflow-web-admin"]) {
                        dirName = appname.split('-')[-1] // 从appname获取目录名
                        sh 'npm config set registry http://10.0.5.33:6532/;'
                        sh 'yarn install;'
                        // 简化环境变量判断
                        switch (params.ENV) {
                            case "EVOFLOW-DEV":
                                buildCmd = 'npm run build:test'
                                break
                            case "EVOFLOW-PRE":
                                buildCmd = 'npm run build:pre'
                                break
                            default:
                                buildCmd = 'npm run build:prod'
                        }
                    } else if (appname in ["evoflow-web-official-website"]) {
                        switch (params.ENV) {
                            case "EVOFLOW-DEV":
                                sh "mv .env.test .env.local"
                                break
                            case "EVOFLOW-PRE":
                                sh "mv .env.pre .env.local"
                                break
                            default:
                                sh "mv .env.production .env.local"
                        }
                    } else {
                        // 对于不匹配的appname，根据ENV执行不同构建命令
                        sh 'pnpm install;'
                        switch (params.ENV) {
                            case "EVOFLOW-DEV":
                                buildCmd = 'pnpm run build:test'
                                break
                            case "EVOFLOW-PRE":
                                buildCmd = 'pnpm run build:pre'
                                break
                            default:
                                buildCmd = 'pnpm run build:prod'
                        }
                    }

                    // 执行构建命令
                    if (buildCmd) {
                        sh buildCmd
                        // 如果dirName存在，移动相应目录
                        if (dirName) {
                            sh "mv ${dirName} build"
                        }
                    }
                    archiveArtifacts artifacts: 'build/**', allowEmptyArchive: true
                }

            }

            stage('构建上传镜像') {
                parallel 'docker': {
                    echo "Build docker image..."
                    // 更改env.sh的镜像地址，为了处理dev、pre、pro不同的镜像地址
                    sh "sed -i 's@DockerRegistry@${imageAddr}@g' ./release/docker/env.sh"

                    // 界面左侧显示构建信息
                    currentBuild.description = "发布环境: ${ENV} \n分支名称: ${BRANCH} \n发布用户: ${buildUser} \n镜像版本号: ${commitInfo.version}"
                    script {
                        // 检查镜像是否存在
                        // def imageExists = sh(script: "docker image ls ${imageAddr}/${chartname} | grep ${commitInfo.version} || true", returnStdout: true).trim()
                        // if (imageExists) {
                        //     echo '镜像已存在，跳过构建'
                        // } else {
                        //     // 构建上传Docker镜像
                        //     sh "./release/docker/buildUpload.sh ${commitInfo.version}"

                        // }
                        sh "./release/docker/buildUpload.sh ${commitInfo.version}"
                    }
                }
            }

            stage('单元测试') {
                echo "单元测试中...."
            }

            stage('质量检测') {
                echo "SonarScanner质量检查扫描中...."
            }
            stage('配置中心加载') {
                echo "Build success, Now Callback Cd..."

                dir("deploy-config") {
                    git([
                            url: "git@mind-git.im30.lan:sinuo/deploy-config.git",
                            branch: "evoflow",
                            credentialsId: 'deploy-config'
                    ])
                    // certs
                    def PGRDIR = pwd()

                    if ( params.ENV == "EVOFLOW-PROD" ){
                        serverEnv.add("KUBECONFIG=$PGRDIR/" + "prod/tke/kube.cfg")
                        serverEnv.add("PROFILE=prod")

                    } else if ( params.ENV == "EVOFLOW-PRE" ){
                        serverEnv.add("KUBECONFIG=$PGRDIR/" + "pre/tke/kube.cfg")
                        serverEnv.add("PROFILE=pre")
                    }else{
                        serverEnv.add("KUBECONFIG=$PGRDIR/" + "dev/tke/kube.cfg")
                        serverEnv.add("PROFILE=dev")
                    }

                    if ( params.Grayscale == true ){
                        if ( params.GrayscaleType == "Based on specific users" ){
                            serverEnv.add("grayTpye=ab")
                        } else {
                            serverEnv.add("grayTpye=gray")
                        }
                    }

                }

            }
            stage('Helm资源构造') {
                    // 切换到指定目录
                    dir('release/k8s/chart') {
                        // 在指定目录下克隆仓库
                        checkout([
                            $class: 'GitSCM',
                            branches: [[name: 'main']],
                            userRemoteConfigs: [[
                                url: 'git@mind-git.im30.lan:sinuo/template-chart.git',
                                credentialsId: 'deploy-config'
                            ]]
                        ])
                    }
            }
        withEnv(serverEnv) {
            if ( params.ENV == "EVOFLOW-PROD"  && params.Grayscale == true ){
                stage('灰度环境构建') {
                        echo "灰度发布中...."
                        // sh "release/k8s/cluster/${PROFILE}/grayscale.sh ${commitInfo.version} ${GrayscaleType}"
                        if ( params.GrayscaleType == "Based on specific users" ){
                            sh "release/k8s/cluster/${PROFILE}/grayscale.sh ${commitInfo.version} ab"
                        } else {
                            sh "release/k8s/cluster/${PROFILE}/grayscale.sh ${commitInfo.version} gray"
                        }

                        // 备份VirtualService，删除上个版本的VirtualService，让新的VirtualService生效
                        def output = sh(script: "kubectl get VirtualServices ${chartname} -o yaml -n ${namespace}", returnStdout: true).trim()
                        writeFile file: 'oldvs.yaml', text: output
                        sh(script: "kubectl delete VirtualService -n ${namespace} ${chartname}")

                        echo '灰度环境构建成功'
                        currentBuild.result = 'SUCCESS'
                        String branch = params.BRANCH
                        String env = params.ENV
                        notifyUtil.graynotifyApp(jobUtil.getRepoName(), branch, env , buildUser)
                }
                stage('灰度结果确认') {

                    try {
                        Grayresult = input(message: '请确认灰度结果:', parameters: [choice(choices: ['验证完成可以上线', '测试失败停止上线'], description: '请确认灰度结果', name: '灰度结果')])
                        echo "grayresult ${Grayresult}"
                    } catch (e) {
                        if (e instanceof org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) {
                            currentBuild.result = 'FAILURE'
                            echo "灰度测试失败，停止上线,删除v2,  VirtualService还原"
                            sh(script: "kubectl apply  -f oldvs.yaml")
                            sh(script: "helm delete -n ${namespace} ${chartname}-${grayTpye}")
                            error("Deployment aborted by user.")
                        } else {
                            throw e
                        }
                    }
                }
                if ( Grayresult == "验证完成可以上线" ){
                    stage('应用部署') {
                            echo '灰度发布验证完成，开始发布到生产环境'
                            sh "release/k8s/cluster/${PROFILE}/deploy.sh ${commitInfo.version}"
                            // 删除灰度发布的v2
                            sh(script: "helm delete -n ${namespace} ${chartname}-${grayTpye}")
                    }
                } else {
                    echo "灰度测试失败，停止上线,删除v2,  VirtualService还原"
                    sh(script: "kubectl apply  -f oldvs.yaml")
                    sh(script: "helm delete -n ${namespace} ${chartname}-${grayTpye}")
                }

            } else {
                stage('应用部署') {
                        echo '未开启灰度发布'
                        sh "release/k8s/cluster/${PROFILE}/deploy.sh ${commitInfo.version}"
                }
            }
        }
        }   catch (e) {
                if (e instanceof org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) {
                    currentBuild.result = 'ABORTED'
                } else {
                    currentBuild.result = 'FAILURE'
                }
                
        }  finally {
            try {
                stage('通知') {
                    echo "通知工作群..."
                    currentBuild.result = 'SUCCESS'
                    echo "currentBuild.result ${currentBuild.result}"
                    String branch = params.BRANCH
                    String env = params.ENV
                    notifyUtil.notifyApp(jobUtil.getRepoName(), branch, env, buildUser)
                }
            } catch (err) {
                echo err.getMessage()
            }
            // deleteDir()
        }
    }
}